using System.Collections.Generic;
using NopSolutions.NopCommerce.BusinessLogic.Products;
using NopSolutions.NopCommerce.LuceneHelper.Tasks;

namespace NopSolutions.NopCommerce.LuceneHelper
{
    public class IndexManager
    {
        public void IndexTask<T>(T task) where T:ITask
        {
            IndexTask(task, true);
        }

        public void IndexTask<T>(T task, bool useQueue) where T : ITask
        {
            IndexTasks(new List<ITask> { task }, useQueue);
        }

        public void IndexTasks<T>(IEnumerable<T> tasks, bool useQueue) where T : ITask
        {
            if (useQueue && LuceneContext.Instance.QueueEnabled)
            {
                LuceneContext.Instance.AddTasks(tasks);
                return;
            }
            var indexers = new Dictionary<LuceneIndexType, IndexWriterWrapper>();
            var searchManager = new SearchManager();
            foreach (var task in tasks)
            {
                if (!indexers.ContainsKey(task.IndexType))
                {
                    indexers.Add(task.IndexType, GetIndexWriter(task.IndexType, task.RebuildIndex));
                }
                task.DoTask(this, searchManager, indexers[task.IndexType]);
            }
            foreach (var indexer in indexers.Values)
            {
                indexer.Dispose();
            }
        }

        public void IndexTasks<T>(IEnumerable<T> tasks) where T : ITask
        {
            IndexTasks(tasks, true);
        }

        public void IndexProduct(Product product, bool forceUpdate)
        {
            IndexTask(new  ProductUpdateTask(product, forceUpdate));
        }

        public void IndexProductVariant(ProductVariant productVariant)
        {
            IndexProduct(productVariant.Product, true);
            ////The only type of variants that effect the product index are the minimum priced variants
            //if(productVariant.ProductVariantId == productVariant.Product.MinimalPriceProductVariant.ProductVariantId)
            //{
            //    int total;
            //    var product = searchManager.SearchProducts(new ProductQuery().WithProductID(productVariant.ProductId), ProductsSortBy.Relevance, 0,
            //                                               1, out total).SingleOrDefault();
            //    if(product == null)
            //    {
            //        //Shouldn't happen, but if there is no product in the index, lets just index the product 
            //        //because it will index the variant also.
            //        IndexProduct(productVariant.Product);
            //    }else
            //    {
                    
            //    }
            //}
        }

        public void IndexCategories()
        {
            IndexTask(new CategoriesUpdateTask());
        }

        public IndexWriterWrapper GetIndexWriter(LuceneIndexType indexType, bool recreate)
        {
            return new IndexWriterWrapper(DirectoryManager.GetIndex(indexType), recreate);
        }

    }
}
